package com.sky.controller.doctor;

import cn.hutool.core.date.DateUtil;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.sky.constants.Constants;
import com.sky.controller.BaseController;
import com.sky.domain.*;
import com.sky.dto.CareHistoryDto;
import com.sky.dto.CareOrderFormDto;
import com.sky.service.CareService;
import com.sky.service.DeptService;
import com.sky.service.PatientService;
import com.sky.service.RegistrationService;
import com.sky.utils.HosDateUtils;
import com.sky.utils.IdGeneratorSnowflake;
import com.sky.utils.ShiroSecurityUtils;
import com.sky.vo.AjaxResult;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author sky
 * @create 2021-07-17 15:31
 */
@RestController
@RequestMapping("doctor/care")
public class CareController extends BaseController {
    @Reference
    private RegistrationService registrationService;
    @Reference
    private PatientService patientService;
    @Reference
    private CareService careService;
    @Autowired
    private DeptService deptService;

    /**
     * 查询待就诊的挂号信息
     */
    @GetMapping("queryToBeSeenRegistration/{schedulingType}")
    public AjaxResult queryToBeSeenRegistration(@PathVariable String schedulingType) {
        // 获取当前用户的部门Id
        Long deptId = ShiroSecurityUtils.getCurrentUser().getDeptId();
        // 获取当前时段
        String subsectionType = HosDateUtils.getCurrentTimeType();
        // 设置要查询的状态只能是挂号单的待就诊的挂号信息
        String regStatus = Constants.REG_STATUS_1;

        // 查询
        List<Registration> list = this.registrationService.queryRegistration(deptId, subsectionType, schedulingType, regStatus, null);
        return AjaxResult.success(list);
    }

    /**
     * 查询就诊中的挂号信息
     */
    @GetMapping("queryVisitingRegistration/{schedulingType}")
    public AjaxResult queryVisitingRegistration(@PathVariable String schedulingType) {
        // 获取当前用户的部门Id
        Long deptId = ShiroSecurityUtils.getCurrentUser().getDeptId();
        // 获取当前用户的Id
        Long userId = ShiroSecurityUtils.getCurrentUser().getUserId();
        // 设置要查询的状态只能是挂号单的就诊中的信息
        String regStatus = Constants.REG_STATUS_2;

        //查询
        List<Registration> list = this.registrationService.queryRegistration(deptId, null, schedulingType, regStatus, userId);
        return AjaxResult.success(list);
    }

    /**
     * 查询就诊完成的挂号信息
     */
    @GetMapping("queryVisitCompletedRegistration/{schedulingType}")
    public AjaxResult queryVisitCompletedRegistration(@PathVariable String schedulingType) {
        // 获取当前用户的部门Id
        Long deptId = ShiroSecurityUtils.getCurrentUser().getDeptId();
        // 获取当前用户的Id
        Long userId = ShiroSecurityUtils.getCurrentUser().getUserId();
        // 设置要查询的状态只能是挂号单的就诊中的信息
        String regStatus = Constants.REG_STATUS_3;

        //查询
        List<Registration> list = this.registrationService.queryRegistration(deptId, null, schedulingType, regStatus, userId);
        return AjaxResult.success(list);
    }

    /**
     * 接诊
     */
    @PostMapping("receivePatient/{regId}")
    public AjaxResult receivePatient(@PathVariable String regId) {
        synchronized (this) { // 防止并发接诊的问题
            // 根据挂号单ID 查询挂号信息
            Registration registration = this.registrationService.queryRegistrationByRegId(regId);
            if (null == registration) {
                return AjaxResult.fail("【" + regId + "】挂号单的不存在，不能接诊");
            }
            // 只有当挂号单的状态 regStatus 为 待就诊 时可以就诊
            if (registration.getRegStatus().equals(Constants.REG_STATUS_1)) {
                registration.setRegStatus(Constants.REG_STATUS_2);//就诊中
                registration.setUserId(ShiroSecurityUtils.getCurrentUser().getUserId());
                registration.setDoctorName(ShiroSecurityUtils.getCurrentUser().getUserName());
                return AjaxResult.toAjax(this.registrationService.updateRegistrationByRegId(registration));
            } else {
                return AjaxResult.fail("【" + regId + "】挂号单的状态不是待就诊状态，不能接诊");
            }
        }
    }

    /**
     * 根据患者ID 获取患者信息、档案信息、病历信息
     */
    @GetMapping("getPatientAllMessageByPatientId/{patientId}")
    public AjaxResult getPatientAllMessageByPatientId(@PathVariable String patientId) {
        // 查询患者信息
        Patient patient = this.patientService.getPatientById(patientId);
        // 查询档案
        PatientFile patientFile = this.patientService.getPatientFileById(patientId);
        // 查询病历表
        List<CareHistory> careHistories = this.careService.queryCareHistoryByPatientId(patientId);
        // 构造结果集
        Map<String, Object> res = new HashMap<>();
        res.put("patient", patient);
        res.put("patientFile", patientFile);
        res.put("careHistoryList", careHistories);
        return AjaxResult.success(res);
    }

    /**
     * 保存病例信息
     */
    @PostMapping("saveCareHistory")
    public AjaxResult saveCareHistory(@RequestBody CareHistoryDto careHistoryDto) {
        careHistoryDto.setUserId(ShiroSecurityUtils.getCurrentUser().getUserId());
        careHistoryDto.setUserName(ShiroSecurityUtils.getCurrentUserName());
        careHistoryDto.setDeptId(ShiroSecurityUtils.getCurrentUser().getDeptId());
        Dept dept = this.deptService.getOne(ShiroSecurityUtils.getCurrentUser().getDeptId());
        careHistoryDto.setDeptName(dept.getDeptName());
        careHistoryDto.setCareDate(DateUtil.date());
        CareHistory ch = this.careService.saveOrUpdateCareHistory(careHistoryDto);
        return AjaxResult.success(ch);
    }

    /**
     * 根据挂号单位ID 查询对应的病历信息
     */
    @GetMapping("getCareHistoryByRegId/{regId}")
    @HystrixCommand
    public AjaxResult getCareHistoryByRegId(@PathVariable String regId) {
        CareHistory careHistory = this.careService.queryCareHistoryByRegId(regId);
        return AjaxResult.success(careHistory);
    }

    /**
     * 根据病历ID 查询处方信息及详情信息
     */
    @GetMapping("queryCareOrdersByChId/{chId}")
    @HystrixCommand
    public AjaxResult queryCareOrdersByChId(@PathVariable String chId) {
        // 查询药用处方
        List<CareOrder> careOrders = this.careService.queryCareOrdersByChId(chId);
        List<Map<String, Object>> res = new ArrayList<>();
        for (CareOrder careOrder : careOrders) {
            Map<String, Object> map = new HashMap<>();
            map.put("careOrder", careOrder);
            // 查询开诊细表
            List<CareOrderItem> careOrderItems = this.careService.queryCareOrderItemsByCoId(careOrder.getCoId());
            map.put("careOrderItems", careOrderItems);
            res.add(map);
        }
        return AjaxResult.success(res);
    }

    /**
     * 保存处方及详情信息
     */
    @PostMapping("saveCareOrderItem")
    @HystrixCommand
    public AjaxResult saveCareOrderItem(@RequestBody @Validated CareOrderFormDto careOrderFormDto) {
        // 根据病例ID 查询病历信息
        CareHistory careHistory = this.careService.queryCareHistoryByChId(careOrderFormDto.getCareOrder().getChId());
        if (null == careHistory) {
            return AjaxResult.fail("病历ID 不存在，请核对后再提交");
        }
        careOrderFormDto.getCareOrder().setCoId(IdGeneratorSnowflake.generatorIdWithPrefix(Constants.ID_PREFIX_CO));
        careOrderFormDto.getCareOrder().setPatientId(careHistory.getPatientId());
        careOrderFormDto.getCareOrder().setPatientName(careHistory.getPatientName());
        careOrderFormDto.getCareOrder().setUserId(ShiroSecurityUtils.getCurrentUser().getUserId());
        careOrderFormDto.getCareOrder().setSimpleUser(ShiroSecurityUtils.getCurrentSimpleUser());
        return AjaxResult.toAjax(this.careService.saveCareOrderItem(careOrderFormDto));
    }

    /**
     * 根据处方详情ID 删除处方详情【只能删除未支付的】
     */
    @DeleteMapping("deleteCareOrderItemById/{itemId}")
    @HystrixCommand
    public AjaxResult deleteCareOrderItemById(@PathVariable String itemId){
        CareOrderItem careOrderItem=this.careService.queryCareOrderItemByItemId(itemId);
        if(null==careOrderItem){
            return AjaxResult.fail("处方详情ID 不存在");
        }
        if(!careOrderItem.getStatus().equals(Constants.ORDER_DETAILS_STATUS_0)){
            return AjaxResult.fail("【"+itemId+"】不是未支付状态，不能删除");
        }
        return AjaxResult.toAjax(this.careService.deleteCareOrderItemByItemId(itemId));
    }

    /**
     * 完成就诊
     */
    @PostMapping("visitComplete/{regId}")
    @HystrixCommand
    public AjaxResult visitComplete(@PathVariable String regId){
        Registration registration=this.registrationService.queryRegistrationByRegId(regId);
        if(null==registration){
            return AjaxResult.fail("【"+regId+"】挂号单号不存在，请核对后再提交");
        }
        if(!registration.getRegStatus().equals(Constants.REG_STATUS_2)){
            return AjaxResult.fail("【"+regId+"】状态不是就诊中状态，不能完成就诊");
        }
        // 更改挂号单的状态
        return AjaxResult.toAjax(this.careService.visitComplete(regId));
    }
}
